/********************************************************************************
* @author: Ternura_xiang
* @email: 2022101883@nit.edu.cn
* @date: Apr 5, 2025
* @version: 1.0
* @description: 显示函数
********************************************************************************/
#include "display.h"


/*-------------变量定义-------------*/
DISPLAY_MODE display_mode;  // 显示界面
uint8_t display_mode_change_flag; // 显示界面更新标志位
DISPLAY_MODE display_mode_select_last;  // 主界面下，上次选择的界面
DISPLAY_MODE display_mode_select_now;   // 主界面下，本次选择的界面
THRESHOLD_MODE threshold_mode;  // 阈值界面下，正在调整的阈值的界面
PWM_SELECT pwm_select_last, pwm_select_now;  // PWM界面下，设置的项目
uint8_t pwm1_mode, pwm2_mode; // PWM开关标志
uint8_t pwm_change;   // PWM更改标志(该位为1，PWM值可以更改，否则为选择需要更改的值)
uint8_t pwm_mode_change_flag; // PWM界面下，PWM开关状态更新标志
uint8_t pwm_duty_change_flag; // PWM界面下，PWM占空比状态更新标志
uint8_t pwm_freq_change_flag; // PWM界面下，PWM频率状态更新标志
uint8_t pwm_duty1, pwm_duty2; // PWM界面下，PWM的占空比值
uint8_t pwm_duty_change_num;  // PWM界面下，调整的占空比位(0->十位, 1->个位)
char display_str_buf[30]; // 显示字符串时的缓冲区

uint16_t uart_date[] = {1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10};
uint16_t uart_date_max = 10;

/*-------------函数定义-------------*/
/**
 * @brief 显示模块初始化
 */
void Display_Init(void){
  // 初始化屏幕
  LCD_Init();
	LCD_Full(COLOR_BLACK);

  // 初始化全局变量
  display_mode = DISPLAY_MODE_MAIN;
  display_mode_change_flag = 1;
}

/**
 * @brief 显示主界面
 * @note 此函数仅内部使用
 */
void Display_Interface_Main(void){
  // 检测到从其他界面切换到主界面
  if(display_mode_change_flag){
    LCD_Full(COLOR_BLACK);

    // 显示标题
    LCD_FullArea(0, 0, 320, 40, COLOR_BLUE);
    sprintf(display_str_buf, "Link");
    LCD_DrawStr(106, 3, display_str_buf, COLOR_BLACK, 3);

    // 显示选项
    sprintf(display_str_buf, "Threshold Set");
    LCD_DrawStr(35, 45, display_str_buf, COLOR_WHITE, 2);
    sprintf(display_str_buf, "ADC");
    LCD_DrawStr(35, 75, display_str_buf, COLOR_WHITE, 2);
    sprintf(display_str_buf, "PWM OUT");
    LCD_DrawStr(35, 105, display_str_buf, COLOR_WHITE, 2);
    sprintf(display_str_buf, "Setting");
    LCD_DrawStr(35, 135, display_str_buf, COLOR_WHITE, 2);

    // 更新标志位
    display_mode_select_now = DISPLAY_MODE_THRESHOLD;
    display_mode_select_last = DISPLAY_MODE_SETTING;  // 设置这里是为了进入下面的if判断
    display_mode_change_flag = 0;
  }

  // 更新选择符号
  if(display_mode_select_now != display_mode_select_last){
    uint16_t y; // 需要显示的坐标

    // 清除上一次的标号
    switch (display_mode_select_last) {
      case (DISPLAY_MODE_THRESHOLD):  y = 45; break;
      case (DISPLAY_MODE_ADC):        y = 75; break;
      case (DISPLAY_MODE_PWM):        y = 105;break;
      case (DISPLAY_MODE_SETTING):    y = 135;break;
    }
    LCD_FullArea(9, y, 34, y+30, COLOR_BLACK);

    // 显示现在的标号
    switch (display_mode_select_now) {
      case (DISPLAY_MODE_THRESHOLD):  y = 45; break;
      case (DISPLAY_MODE_ADC):        y = 75; break;
      case (DISPLAY_MODE_PWM):        y = 105;break;
      case (DISPLAY_MODE_SETTING):    y = 135;break;
    }
    sprintf(display_str_buf, ">");
    LCD_DrawStr(9, y, display_str_buf, COLOR_RED, 2);

    // 更新标志位
    display_mode_select_last = display_mode_select_now;
  }
}

/**
 * @brief 显示阈值调整界面
 * @note 此函数仅内部使用
 */
void Display_Interface_Threshold(void){
  // 检测到从其他界面切换到主界面
  if(display_mode_change_flag){
    LCD_Full(COLOR_BLACK);

    // 显示标题
    LCD_FullArea(0, 0, 320, 40, COLOR_BLUE);
    sprintf(display_str_buf, "Threshold");
    LCD_DrawStr(38, 3, display_str_buf, COLOR_BLACK, 3);

    // 更新标志位
    threshold_mode = THRESHOLD_MODE_L;
    display_mode_change_flag = 0;
  }

  // 更新图表区
  uint16_t data_length;
  switch (threshold_mode) {
    case THRESHOLD_MODE_L:  data_length = 100; break;
    case THRESHOLD_MODE_A:  data_length = 256; break;
    case THRESHOLD_MODE_B:  data_length = 256; break;
  }
  LCD_DrawHistogram(0, 50, 320, 140, COLOR_BLACK, \
    uart_date, data_length, uart_date_max, COLOR_WHITE, 1, COLOR_RED);
}

/**
 * @brief 显示底边引脚信息
 * @note 此函数仅内部使用
 *
 */
void Display_Interface_Bottom(void){
  LCD_FullArea(0, 205, 27, 247, COLOR_RED);
  sprintf(display_str_buf, "3V3");
  LCD_DrawStr(0, 218, display_str_buf, COLOR_WHITE, 1);
  LCD_FullArea(28, 205, 73, 247, COLOR_OLIVE);
  sprintf(display_str_buf, " C15 ");
  LCD_DrawStr(28, 209, display_str_buf, COLOR_WHITE, 1);
  sprintf(display_str_buf, " C140 ");
  LCD_DrawStr(27, 225, display_str_buf, COLOR_WHITE, 1);
  LCD_FullArea(74, 205, 101, 247, COLOR_GRAY);
  sprintf(display_str_buf, "GND");
  LCD_DrawStr(74, 218, display_str_buf, COLOR_WHITE, 1);
  
  LCD_FullArea(103, 205, 112, 247, COLOR_RED);
  LCD_FullArea(113, 205, 167, 247, COLOR_OLIVE);
  sprintf(display_str_buf, " ADC1 ");
  LCD_DrawStr(113, 209, display_str_buf, COLOR_WHITE, 1);
  sprintf(display_str_buf, " ADC2 ");
  LCD_DrawStr(113, 225, display_str_buf, COLOR_WHITE, 1);
  LCD_FullArea(168, 205, 177, 247, COLOR_GRAY);

  LCD_FullArea(179, 205, 188, 247, COLOR_RED);
  LCD_FullArea(189, 205, 234, 247, COLOR_OLIVE);
  sprintf(display_str_buf, " B10 ");
  LCD_DrawStr(189, 209, display_str_buf, COLOR_WHITE, 1);
  sprintf(display_str_buf, " PB2 ");
  LCD_DrawStr(189, 225, display_str_buf, COLOR_WHITE, 1);
  LCD_FullArea(235, 205, 244, 247, COLOR_GRAY);

  LCD_FullArea(246, 205, 255, 247, COLOR_RED);
  LCD_FullArea(256, 205, 310, 247, COLOR_OLIVE);
  sprintf(display_str_buf, " PWM1 ");
  LCD_DrawStr(256, 209, display_str_buf, COLOR_WHITE, 1);
  sprintf(display_str_buf, " PWM2 ");
  LCD_DrawStr(256, 225, display_str_buf, COLOR_WHITE, 1);
  LCD_FullArea(310, 205, 319, 247, COLOR_GRAY);
}

/**
 * @brief 显示ADC界面
 * @note 此函数仅内部使用
 */
void Display_Interface_ADC(void){
  // 检测到从其他界面切换到主界面
  if(display_mode_change_flag){
    LCD_Full(COLOR_BLACK);

    // 显示标题
    LCD_FullArea(0, 0, 320, 40, COLOR_BLUE);
    sprintf(display_str_buf, "ADC");
    LCD_DrawStr(119, 3, display_str_buf, COLOR_BLACK, 3);

    // 显示底边
    Display_Interface_Bottom();

    // 更新标志位
    display_mode_change_flag = 0;
  }
}

/**
 * @brief 显示PWM输出界面
 * @note 此函数仅内部使用
 */
void Display_Interface_PWM(void){
  // 检测到从其他界面切换到主界面
  if(display_mode_change_flag){
    LCD_Full(COLOR_BLACK);

    // 显示标题
    LCD_FullArea(0, 0, 320, 40, COLOR_BLUE);
    sprintf(display_str_buf, "PWM");
    LCD_DrawStr(119, 3, display_str_buf, COLOR_BLACK, 3);

    // 显示选项、信息
    sprintf(display_str_buf, "Freq:");
    LCD_DrawStr(35, 45, display_str_buf, COLOR_WHITE, 2);
    sprintf(display_str_buf, "PWM1:");
    LCD_DrawStr(35, 75, display_str_buf, COLOR_YELLOWGREEN, 2);
    sprintf(display_str_buf, "Duty_1:");
    LCD_DrawStr(35, 105, display_str_buf, COLOR_YELLOWGREEN, 2);
    sprintf(display_str_buf, "PWM2:");
    LCD_DrawStr(35, 135, display_str_buf, COLOR_ORANGE, 2);
    sprintf(display_str_buf, "Duty_2:");
    LCD_DrawStr(35, 165, display_str_buf, COLOR_ORANGE, 2);

    // 显示底边
    Display_Interface_Bottom();

    // 更新标志位
    pwm_select_now = PWM_SELECT_FREQ;
    pwm_select_last = PWM_SELECT_DUTY2;
    pwm_mode_change_flag = 1;
    pwm_duty_change_flag = 1;
    pwm_freq_change_flag = 1;
    display_mode_change_flag = 0;
    pwm_duty_change_num = 0;
  }

  // 更新PWM开启/关闭
  if(pwm_mode_change_flag){
    if(pwm1_mode){
      LCD_FullArea(149, 73, 206, 99, COLOR_GREEN);
      sprintf(display_str_buf, "ON");
      LCD_DrawStr(150, 75, display_str_buf, COLOR_WHITE, 2);
    }
    else{
      LCD_FullArea(149, 73, 206, 99, COLOR_RED);
      sprintf(display_str_buf, "OFF");
      LCD_DrawStr(150, 75, display_str_buf, COLOR_WHITE, 2);
    }
    if(pwm2_mode){
      LCD_FullArea(149, 133, 206, 159, COLOR_GREEN);
      sprintf(display_str_buf, "ON");
      LCD_DrawStr(150, 135, display_str_buf, COLOR_WHITE, 2);
    }
    else{
      LCD_FullArea(149, 133, 206, 159, COLOR_RED);
      sprintf(display_str_buf, "OFF");
      LCD_DrawStr(150, 135, display_str_buf, COLOR_WHITE, 2);
    }
    pwm_mode_change_flag = 0;
  }

  // 更新PWM频率
  if(pwm_freq_change_flag){
    printf("%d", TIM1->ARR);
    LCD_FullArea(130, 45, 300, 72, COLOR_BLACK);  // 刷新防止混叠
    uint32_t pwm_freq = 1000000 / (TIM1->ARR+1);  // 计算频率
    // 根据频率大小设置显示
    if(pwm_freq > 1000){
      sprintf(display_str_buf, "%5.2fKHz", ((float)pwm_freq/1000.0));
    }
    else{
      sprintf(display_str_buf, "%.dHz", pwm_freq);
    }
    LCD_DrawStr(130, 45, display_str_buf, COLOR_WHITE, 2);
    // 更新标志位
    pwm_freq_change_flag = 0;
  }

  // 更新PWM占空比
  if(pwm_duty_change_flag){
    LCD_FullArea(170, 105, 224, 130, COLOR_BLACK);
    // 提示正在更改哪一位(更改显示颜色)
    static uint16_t color_1_10, color_2_10, color_1_1, color_2_1;  // 存储显示的颜色
    switch (pwm_duty_change_num) {
      case 0: color_1_10=color_2_10=COLOR_BLUE; color_1_1=color_2_1=COLOR_WHITE; break;
      case 1: color_1_10=color_2_10=COLOR_WHITE; color_1_1=color_2_1=COLOR_BLUE; break;
    }
    if(pwm_change == 1 && pwm_select_now == PWM_SELECT_DUTY1){
      color_2_10 = color_2_1 = COLOR_WHITE;}
    else if (pwm_change == 1 && pwm_select_now == PWM_SELECT_DUTY2){
      color_1_10 = color_1_1 = COLOR_WHITE;}
    else{
      color_1_10 = color_2_10 = color_1_1 = color_2_1 = COLOR_WHITE;}
    // 显示PWM1
    sprintf(display_str_buf, "%d", (uint8_t)(pwm_duty1 / 10));
    LCD_DrawStr(170, 105, display_str_buf, color_1_10, 2);
    sprintf(display_str_buf, "%d", (uint8_t)(pwm_duty1 % 10));
    LCD_DrawStr(188, 105, display_str_buf, color_1_1, 2);
    LCD_DrawChar(206, 105, '%', COLOR_WHITE, 2);
    // 显示PWM2
    LCD_FullArea(170, 165, 224, 190, COLOR_BLACK);
    sprintf(display_str_buf, "%d", (uint8_t)(pwm_duty2 / 10));
    LCD_DrawStr(170, 165, display_str_buf, color_2_10, 2);
    sprintf(display_str_buf, "%d", (uint8_t)(pwm_duty2 % 10));
    LCD_DrawStr(188, 165, display_str_buf, color_2_1, 2);
    LCD_DrawChar(206, 165, '%', COLOR_WHITE, 2);
    pwm_duty_change_flag = 0;
  }

  // 更新选项箭头
  if(pwm_select_now != pwm_select_last){
    uint16_t y; // 需要显示的坐标

    // 清除上一次的标号
    switch (pwm_select_last) {
      case (PWM_SELECT_FREQ):         y = 45; break;
      case (PWM_SELECT_PWM1):         y = 75; break;
      case (PWM_SELECT_DUTY1):        y = 105;break;
      case (PWM_SELECT_PWM2):         y = 135;break;
      case (PWM_SELECT_DUTY2):        y = 165;break;
    }
    LCD_FullArea(9, y, 34, y+30, COLOR_BLACK);

    // 显示现在的标号
    switch (pwm_select_now) {
      case (PWM_SELECT_FREQ):         y = 45; break;
      case (PWM_SELECT_PWM1):         y = 75; break;
      case (PWM_SELECT_DUTY1):        y = 105;break;
      case (PWM_SELECT_PWM2):         y = 135;break;
      case (PWM_SELECT_DUTY2):        y = 165;break;
    }
    sprintf(display_str_buf, ">");
    LCD_DrawStr(9, y, display_str_buf, COLOR_RED, 2);

    // 更新标志位
    pwm_select_last = pwm_select_now;
  }
}

/**
 * @brief 显示设置界面
 * @note 此函数仅内部使用
 */
 void Display_Interface_Setting(void){
  // 检测到从其他界面切换到主界面
  if(display_mode_change_flag){
    LCD_Full(COLOR_BLACK);

    // 显示标题
    LCD_FullArea(0, 0, 320, 40, COLOR_BLUE);
    sprintf(display_str_buf, "Setting");
    LCD_DrawStr(65, 3, display_str_buf, COLOR_BLACK, 3);

    // 更新标志位
    display_mode_change_flag = 0;
  }
}

/**
 * @brief 显示主函数
 */
void Display_Process(void){
  switch (display_mode) {
    case DISPLAY_MODE_MAIN:       Display_Interface_Main();       break;
    case DISPLAY_MODE_THRESHOLD:  Display_Interface_Threshold();  break;
    case DISPLAY_MODE_ADC:        Display_Interface_ADC();        break;
    case DISPLAY_MODE_PWM:        Display_Interface_PWM();        break;
    case DISPLAY_MODE_SETTING:    Display_Interface_Setting();    break;
  }
}
